package com.jdd.modules.configcartype.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.andyczy.java.excel.ExcelUtils;
import com.jdd.common.api.vo.Result;
import com.jdd.common.aspect.annotation.*;
import com.jdd.common.constant.JddConstant;
import com.jdd.common.system.query.QueryGenerator;
import com.jdd.common.system.vo.LoginUser;
import com.jdd.common.util.CarType;
import com.jdd.common.util.LoginUserUtils;
import com.jdd.common.util.SnowFlakeUtil;
import com.jdd.common.util.excel.entity.params.ExportParams;
import com.jdd.common.util.excel.web.entity.vo.NormalExcelConstants;
import com.jdd.common.util.excel.web.view.EasypoiSingleExcelView;
import com.jdd.modules.configcartype.entity.ConfigCarType;
import com.jdd.modules.configcartype.service.IConfigCarTypeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.io.InputStream;
import java.util.*;

/**
 * @Description: 车辆类型管理
 * @Author: jdd
 * @Date: 2021-02-18
 * @Version: V1.0
 */
@Slf4j
@Api(tags = "车辆类型管理")
@RestController
@RequestMapping("/ConfigCarType/configCarType")
public class ConfigCarTypeController {
    @Resource
    private IConfigCarTypeService configCarTypeService;

    private String parkCode;
    /**
     * 月租车车辆类型列表查询,根据指定车场查询月租车类型
     *
     * @param
     * @return
     */
    @AutoLog(value = "车辆类型列表查询，月租车车辆类型列表查询,根据指定车场查询月租车类型")
    @ApiOperation(value = "车辆类型列表查询，月租车车辆类型列表查询,根据指定车场查询月租车类型", notes = "车辆类型列表查询，月租车车辆类型列表查询,根据指定车场查询月租车类型")
    @GetMapping(value = "/parkMonthlyCarTypeList")
    public Result<List<ConfigCarType>> parkMonthlyCarTypeList() {
        //车辆类型与车场关联，必须要有parkCode值，查询时如果选择了车辆类型，提示必须选择车场
        Result<List<ConfigCarType>> result = new Result<>();
        try {
            LambdaQueryWrapper<ConfigCarType> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ConfigCarType::getCarType, JddConstant.StringNumber.STRING_ONE);
            List<ConfigCarType> list = configCarTypeService.list(wrapper);
            result.setResult(list);
            result.setSuccess(true);
            return result;
        } catch (Exception e) {
            result.setSuccess(false);
            return result;
        }
    }

    /**
     * 分页列表查询
     *
     * @param configCarType
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    @AutoLog(value = "车辆类型管理-分页列表查询")
    @ApiOperation(value = "车辆类型管理-分页列表查询", notes = "车辆类型管理-分页列表查询")
    @GetMapping(value = "/list")
    public Result<IPage<ConfigCarType>> queryPageList(ConfigCarType configCarType,
                                                      @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                      @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                                      String startTime, String endTime,
                                                      HttpServletRequest req) {
        Result<IPage<ConfigCarType>> result = new Result<IPage<ConfigCarType>>();
        QueryWrapper<ConfigCarType> queryWrapper = QueryGenerator.initQueryWrapper(configCarType, req.getParameterMap());
        if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
            queryWrapper.and(wrapper -> wrapper.lambda().ge(ConfigCarType::getCreateTime, startTime + " 00:00:00").le(ConfigCarType::getCreateTime, endTime + " 23:59:59"));
        }
        Page<ConfigCarType> page = new Page<ConfigCarType>(pageNo, pageSize);
        IPage<ConfigCarType> pageList = configCarTypeService.page(page, queryWrapper);
        result.setSuccess(true);
        result.setResult(pageList);
        return result;
    }

    /**
     * 编辑
     *
     * @param configCarType
     * @return
     */
    @AutoLog(value = "车辆类型管理-编辑")
    @ApiOperation(value = "车辆类型管理-编辑", notes = "车辆类型管理-编辑")
    @PutMapping(value = "/edit")
    @OperationLogDetail(detail = "车辆类型管理，编辑", level = LogLevelType.ONE, operationType = OperationType.UPDATE, operationUnit = OperationUnit.UNKNOWN)
    public Result<ConfigCarType> edit(@RequestBody ConfigCarType configCarType) {
        Result<ConfigCarType> result = new Result<ConfigCarType>();
        ConfigCarType configCarTypeEntity = configCarTypeService.getById(configCarType.getId());
        if (configCarTypeEntity == null) {
            result.error500("未找到对应实体");
        } else {
            boolean ok = configCarTypeService.updateEntity(configCarType);
            //TODO 返回false说明什么？
            if (ok) {
                result.success("修改成功!");
            }
        }
        return result;
    }

    /**
     * 车辆类型列表查询
     *
     * @param
     * @return
     */
    @AutoLog(value = "车辆类型列表查询")
    @ApiOperation(value = "车辆类型列表查询", notes = "车辆类型列表查询")
    @GetMapping(value = "/carTypeList")
    public Result<List<ConfigCarType>> carTypeList() {
        Result<List<ConfigCarType>> result = new Result<List<ConfigCarType>>();
        try {
            List<ConfigCarType> list = configCarTypeService.getCarTypeList();
            result.setResult(list);
            result.setSuccess(true);
            return result;
        } catch (Exception e) {
            result.setSuccess(false);
            return result;
        }
    }

    /**
     * 车辆类型列表查询,根据指定车场查询
     *
     * @param
     * @return
     */
    @AutoLog(value = "车辆类型列表查询，根据指定车场查询")
    @ApiOperation(value = "车辆类型列表查询，根据指定车场查询", notes = "车辆类型列表查询，根据指定车场查询")
    @RequestMapping(value = "/parkCarTypeList")
    public Result<List<ConfigCarType>> parkCarTypeList() {
        Result<List<ConfigCarType>> result = new Result<>();
        try {
            LambdaQueryWrapper<ConfigCarType> wrapper=new LambdaQueryWrapper<>();
            wrapper.in(ConfigCarType::getCarType,Arrays.asList(JddConstant.StringNumber.STRING_ZERO));
            List<ConfigCarType> list = configCarTypeService.list(wrapper);
            result.setResult(list);
            result.setSuccess(true);
            return result;
        } catch (Exception e) {
            result.setSuccess(false);
            return result;
        }
//        }
    }

    @AutoLog(value = "得到指定车场的临时车类型列表")
    @ApiOperation(value = "得到指定车场的临时车类型列表",notes = "得到指定车场的临时车类型列表")
    @RequestMapping(value = "/getTemporaryCarList")
    public Result<List<ConfigCarType>> getTemporaryCarList(ConfigCarType configCarType,HttpServletRequest req){
        Result<List<ConfigCarType>> result = new Result<>();
        LoginUser loginUser = LoginUserUtils.getLoginUser();
        LambdaQueryWrapper<ConfigCarType> queryWrapper = new LambdaQueryWrapper<>();
        if(StringUtils.isNotBlank(loginUser.getParkCode()))
        {
            queryWrapper.eq(ConfigCarType::getParkCode,loginUser.getParkCode());
        }else {
            queryWrapper.eq(ConfigCarType::getParkCode,configCarType.getParkCode());
        }
        List<String> carType = new ArrayList<String>();
        carType.add(JddConstant.StringNumber.STRING_ZERO);
        carType.add(JddConstant.StringNumber.STRING_TWO);
        queryWrapper.in(ConfigCarType::getCarType,carType);
        List<ConfigCarType> pageList = configCarTypeService.list(queryWrapper);
        result.setSuccess(true);
        result.setResult(pageList);
        return result;
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @AutoLog(value = "车辆类型管理-通过id删除")
    @ApiOperation(value = "车辆类型管理-通过id删除", notes = "车辆类型管理-通过id删除")
    @DeleteMapping(value = "/delete")
    @OperationLogDetail(detail = "车辆类型管理，通过id删除", level = LogLevelType.ONE, operationType = OperationType.DELETE, operationUnit = OperationUnit.UNKNOWN)
    public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
        try {
            configCarTypeService.deleteEntityById(id);
        } catch (Exception e) {
            log.error("删除失败", e.getMessage());
            return Result.error("删除失败!");
        }
        return Result.ok("删除成功!");
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "车辆类型管理-批量删除")
    @ApiOperation(value = "车辆类型管理-批量删除", notes = "车辆类型管理-批量删除")
    @DeleteMapping(value = "/deleteBatch")
    @OperationLogDetail(detail = "车辆类型管理，批量删除", level = LogLevelType.ONE, operationType = OperationType.DELETE, operationUnit = OperationUnit.UNKNOWN)
    public Result<ConfigCarType> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        Result<ConfigCarType> result = new Result<ConfigCarType>();
        if (ids == null || "".equals(ids.trim())) {
            result.error500("参数不识别！");
        } else {
            configCarTypeService.deleteEntityByIds(Arrays.asList(ids.split(",")));
            result.success("删除成功!");
        }
        return result;
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    @AutoLog(value = "车辆类型管理-通过id查询")
    @ApiOperation(value = "车辆类型管理-通过id查询", notes = "车辆类型管理-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<ConfigCarType> queryById(@RequestParam(name = "id", required = true) String id) {
        Result<ConfigCarType> result = new Result<ConfigCarType>();
        ConfigCarType configCarType = configCarTypeService.findCarTypeById(id);
        if (configCarType == null) {
            result.error500("未找到对应实体");
        } else {
            result.setResult(configCarType);
            result.setSuccess(true);
        }
        return result;
    }

    /**
     * 导出excel
     *
     * @param request
     * @param response
     */
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response, ConfigCarType configCarType) {
        // Step.1 组装查询条件
        QueryWrapper<ConfigCarType> queryWrapper = QueryGenerator.initQueryWrapper(configCarType, request.getParameterMap());
        //Step.2 AutoPoi 导出Excel
        ModelAndView mv = new ModelAndView(new EasypoiSingleExcelView());
        List<ConfigCarType> pageList = configCarTypeService.list(queryWrapper);
        //导出文件名称
        mv.addObject(NormalExcelConstants.FILE_NAME, "车辆类型管理列表");
        mv.addObject(NormalExcelConstants.CLASS, ConfigCarType.class);
        mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("车辆类型管理列表数据", "导出信息"));
        mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
        return mv;
    }

    /**
     * 通过excel导入数据
     *
     * @param
     * @param
     * @param file
     * @return
     */
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(@RequestParam("file") @NotNull MultipartFile file) throws Exception {
        //获取文件名
        String fileName = file.getOriginalFilename();
        //  第一个表格从第三行开始获取
        HashMap hashMapIndex = new HashMap(1);
        hashMapIndex.put(1, 3);
        String[] sheetNames = new String[]{"导入测试"};
        InputStream inputStream = file.getInputStream();
        Workbook book = null;
        String hssfType = "xls";
        String xssfType = "xlsx";
        try {
            //获取文件后缀名
            String extName = fileName.substring(fileName.lastIndexOf('.') + 1);
            if (StringUtils.equals(hssfType, extName)) {
                book = new HSSFWorkbook(inputStream);
            } else if (StringUtils.equals(xssfType, extName)) {
                book = new XSSFWorkbook(inputStream);
            } else {
                return Result.error("无法识别的Excel文件,请下载模板文件,进行导入!");
            }

            List<ConfigCarType> configCarTypeList = new ArrayList<>();
            ExcelUtils excelUtils = ExcelUtils.initialization();
            excelUtils.setDateFormatStr("yyyy-MM-dd HH:mm:ss");
            List<List<LinkedHashMap<String, String>>> list = ExcelUtils.importForExcelData(book, sheetNames, hashMapIndex, null);
            if (null != list) {
                configCarTypeService.removeByParkCode();
            }
            for (List<LinkedHashMap<String, String>> linkedHashMaps : list) {
                int i = 0;
                for (LinkedHashMap<String, String> linkedHashMap : linkedHashMaps) {
                    if (StringUtils.isNotBlank(linkedHashMap.get("0"))) {
                        ConfigCarType configCarType = new ConfigCarType();
                        //校验表格车场编号跟配置文件配置编号是否相同
                        log.info("================" + linkedHashMap.get("0"));
                        if (parkCode.equals(linkedHashMap.get("0"))) {
                            configCarType.setParkCode(linkedHashMap.get("0"));
                        } else {
                            return Result.error("车场编号为:{" + parkCode + "}当前导入表格中存在不同车场编号");
                        }
                        configCarType.setId(SnowFlakeUtil.getId());
                        configCarType.setParkName(linkedHashMap.get("1"));
                        configCarType.setCarTypeName(linkedHashMap.get("2"));
                        configCarType.setDefaultName(linkedHashMap.get("3"));
                        configCarType.setCarTypeNo(linkedHashMap.get("4"));
                        configCarType.setCarType(linkedHashMap.get("5"));
                        configCarType.setIsOpen(linkedHashMap.get("6"));
                        if (StringUtils.isNotBlank(configCarType.getParkCode())) {
                            configCarType.setSortNo(i);
                            i++;
                            configCarTypeList.add(configCarType);
                        }
                    }
                }
            }
            configCarTypeService.saveConfigCarTypeByList(configCarTypeList);
            return Result.ok("导入文件成功！");
        } catch (Exception e) {
            return Result.error("文件导入失败！");
        }
    }
}
